﻿// --------------------------------
// <copyright file="WorkItemScheduler.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Lukáš Molnár</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>2. 4. 2012 8:31:02</date>

// <summary>
// 
// </summary>
// --------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using FITClub.Util;

namespace FITClub.Episode1.Components
{
    /// <summary>
    /// Hold Workers for each priority and 
    /// </summary>
    public class WorkItemScheduler
    {
        public OneTimeWorker[] Workers { get; private set; }
        public int MaxPriority { get { return this.Workers.Length-1; } }

        private SpinLock spinlock;

        public static WorkItemScheduler Current { get; private set; }

        internal WorkItemScheduler(Game game, int priorities)
        {
            this.Workers = new OneTimeWorker[priorities];
            for (int i = 0; i < priorities; i++)
            {
                this.Workers[i] = new OneTimeWorker(game);
            }
            this.spinlock = new SpinLock(100);
            Current = this;
        }

        /// <summary>
        /// Adds work item into specified priority queue.
        /// </summary>
        /// <param name="wi"></param>
        /// <param name="priority"></param>
        public void Schedule(IWorkItem wi, int priority)
        {
            this.Workers[priority].Schedule(wi);
        }

        /// <summary>
        /// Adds work item into specified priority queue and ensures synchronization using spin lock.
        /// </summary>
        /// <param name="wi"></param>
        /// <param name="priority"></param>
        public void ScheduleSynchronized(IWorkItem wi, int priority)
        {
            spinlock.Lock();
            this.Workers[priority].Schedule(wi);
            spinlock.Unlock();
        }
    }
}
